﻿#define _CRT_SECURE_NO_WARNINGS 1

//本篇博客主题：类成员函数-----赋值运算符重载，为什么默认实现可能不够？

#include<iostream>
using namespace std;

//为什么默认实现可能不够？

class Student
{
public:
	void Init(const char* name,int year,int month,int day)
	{
		strcpy(_name, name);
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << "学生姓名：" << _name << endl;
		cout << "学生入学时间：" 
			 << _year   << "/"
			 << _month  << "/"
			 << _day
			 << endl;
	}
	//private:
	char _name[20];
	int _year;
	int _month;
	int _day;
};

bool student_compare(const Student& s1, const Student& s2)
{
	if (s1._year < s2._year)
	{
		return true;
	}
	else if (s1._year == s2._year)
	{
		if (s1._month < s2._month)
		{
			return true;
		}
		else if (s1._month == s2._month)
		{
			if (s1._day < s2._day)
			{
				return s1._day < s2._day;
			}
		}
	}

	return false;
}


int main()
{
	Student stu1;
	stu1.Init("zhangsan", 2023, 9, 9);

	Student stu2;
	stu2.Init("wangming", 2022, 9, 15);

	cout << student_compare(stu1, stu2) << endl;

	cout << student_compare(stu2, stu1) << endl;

	return 0;
}

//2.1 运算符重载的概念
class Student
{
public:
	void Init(const char* name,int year,int month,int day)
	{
		strcpy(_name, name);
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << "学生姓名：" << _name << endl;
		cout << "学生入学时间：" 
			 << _year   << "/"
			 << _month  << "/"
			 << _day
			 << endl;
	}
	private:
	char _name[20];
	int _year;
	int _month;
	int _day;
};

bool operator<(const Student& s1, const Student& s2)
{
	if (s1._year < s2._year)
	{
		return true;
	}
	else if (s1._year == s2._year)
	{
		if (s1._month < s2._month)
		{
			return true;
		}
		else if (s1._month == s2._month)
		{
			if (s1._day < s2._day)
			{
				return s1._day < s2._day;
			}
		}
	}

	return false;
}


int main()
{
	Student stu1;
	stu1.Init("zhangsan", 2023, 9, 9);

	Student stu2;
	stu2.Init("wangming", 2022, 9, 15);

	cout << (stu1 < stu2) << endl;

	cout << (stu2 < stu1) << endl;

	return 0;
}

// 2.3 有哪些运算符可以重载

class Testpm
{
public:
	void m_func1() 
	{ 
		cout << "m_func1\n"; 
	}
	int m_num;
};

void (Testpm::*pmfn)() = &Testpm::m_func1; 
// 定义指向类成员函数的指针 pmfn，Testpm::* 表示这是一个指向 Testpm 类的成员函数的指针

int Testpm::* pmd = &Testpm::m_num;	
//定义指向类成员变量的指针 pmd，Testpm::* 表示这是一个指向 Testpm 类的成员变量的指针

int main() 
{
	Testpm ATestpm;
	//对象实例化
	Testpm* pTestpm = new Testpm;
	//Testpm*: 这表示 pTestpm 是一个指向 Testpm 类型的指针。
	//new Testpm: 这是使用 new 运算符创建 Testpm 类的一个实例。
	//new 运算符动态地分配内存来存储对象，并返回指向该对象的指针。
	//在这里，我们创建了一个 Testpm 类的对象，并将其地址赋值给 pTestpm 指针。

	// 访问类对象成员函数
	(ATestpm.*pmfn)(); 
	//通过实例对象调用成员函数
	//pmfn是指针，它被解引用以获取成员函数的地址。
	(pTestpm->*pmfn)(); 
	//x-> == (*x).
	//(pTestpm->*pmfn)(); == ((*pTestpm).*pmfn) 
	//通过指针对象调用成员函数。由于 * 的优先级低于函数调用，所以需要使用括号

	// 访问成员变量
	ATestpm.*pmd = 1;
	//通过实例对象访问成员变量
	pTestpm->*pmd = 2; 
	//通过指针对象访问成员变量

	cout << ATestpm.*pmd << endl 
		// 输出实例对象的成员变量
		<< pTestpm->*pmd << endl; 
		// 输出指针对象的成员变量
	delete pTestpm;
}

//三、如何解决private限定访问情况？ 
//3.1 使用成员函数来获取成员变量
class Student
{
public:
	void Init(const char* name,int year,int month,int day)
	{
		strcpy(_name, name);
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << "学生姓名：" << _name << endl;
		cout << "学生入学时间：" 
			 << _year   << "/"
			 << _month  << "/"
			 << _day
			 << endl;
	}

	int GetYear() const
	{
		return _year;
	}

	int GetMonth() const
	{
		return _month;
	}

	int GetDay() const
	{
		return _day;
	}
private:
	char _name[20];
	int _year;
	int _month;
	int _day;
};
	
bool student_compare(const Student& s1, const Student& s2)
{
	if (s1.GetYear() < s2.GetYear())
	{
		return true;
	}
	else if (s1.GetYear() == s2.GetYear())
	{
		if (s1.GetMonth() < s2.GetMonth())
		{
			return true;
		}
		else if (s1.GetMonth() == s2.GetMonth())
		{
			if (s1.GetDay() < s2.GetDay())
			{
				return s1.GetDay() < s2.GetDay();
			}
		}
	}
	
	return false;
}
	
int main()
{
	Student stu1;
	stu1.Init("zhangsan", 2023, 9, 9);
	
	Student stu2;
	stu2.Init("wangming", 2022, 9, 15);
	
	cout << student_compare(stu1, stu2) << endl;
	
	cout << student_compare(stu2, stu1) << endl;
	
	return 0;
}

 //2.4 赋值运算符重载

class Student
{
public:
	void Init(const char* name, int year, int month, int day)
	{
		strcpy(_name, name);
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << "学生姓名：" << _name << endl;
		cout << "学生入学时间："
			<< _year << "/"
			<< _month << "/"
			<< _day
			<< endl;
	}
	Student& operator=(const Student& s)
	{
		if (this != &s)
		{
			strcpy(_name, s._name);
			_year = s._year;
			_month = s._month;
			_day = s._day;
		}

		return *this;
	}

private:
	char _name[20];
	int _year;
	int _month;
	int _day;
};

int main()
{
	Student stu1;
	stu1.Init("zhangsan", 2023, 9, 9);

	Student stu2;
	stu2.Init("wangming", 2022, 9, 15);

	Student stu3;
	stu3.Init("xiaohong", 2021, 9, 16);
	stu3 = stu1 = stu2;

	stu1.Print();
	stu3.Print();

	return 0;
}

//3.2运算符重载作为类成员函数

class Student
{
public:
	void Init(const char* name,int year,int month,int day)
	{
		strcpy(_name, name);
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << "学生姓名：" << _name << endl;
		cout << "学生入学时间：" 
			 << _year   << "/"
			 << _month  << "/"
			 << _day
			 << endl;
	}

	bool student_compare(const Student& s1)
	{
		if (_year < s1._year)
		{
			return true;
		}
		else if (_year == s1._year)
		{
			if (_month < s1._month)
			{
				return true;
			}
			else if (_month == s1._month)
			{
				if (_day < s1._day)
				{
					return _day < s1._day;
				}
			}
		}

		return false;
	}

private:
	char _name[20];
	int _year;
	int _month;
	int _day;
};


int main()
{
	Student stu1;
	stu1.Init("zhangsan", 2023, 9, 9);

	Student stu2;
	stu2.Init("wangming", 2022, 9, 15);

	cout << stu1.student_compare(stu2) << endl;

	cout << stu2.student_compare(stu1) << endl;

	return 0;
}

//3.3友元

class Student
{
public:
	void Init(const char* name,int year,int month,int day)
	{
		strcpy(_name, name);
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << "学生姓名：" << _name << endl;
		cout << "学生入学时间：" 
			 << _year   << "/"
			 << _month  << "/"
			 << _day
			 << endl;
	}

	friend bool student_compare(const Student& s1, const Student& s2);

private:
	char _name[20];
	int _year;
	int _month;
	int _day;
};

bool student_compare(const Student& s1, const Student& s2)
{
	if (s1._year < s2._year)
	{
		return true;
	}
	else if (s1._year == s2._year)
	{
		if (s1._month < s2._month)
		{
			return true;
		}
		else if (s1._month == s2._month)
		{
			if (s1._day < s2._day)
			{
				return s1._day < s2._day;
			}
		}
	}

	return false;
}


int main()
{
	Student stu1;
	stu1.Init("zhangsan", 2023, 9, 9);

	Student stu2;
	stu2.Init("wangming", 2022, 9, 15);

	cout << student_compare(stu1, stu2) << endl;

	cout << student_compare(stu2, stu1) << endl;

	return 0;
}